/**
 * Mock Request Router
 * @author Wangtd
 */
var express = require('express');
var router = express.Router();
var fs = require('fs');
var path = require('path');
var httpRequest = require('request');
var config = require('../config.js');

router.post('/module/get', function(request, response) {
    var filedir = path.join(__dirname, config.mockDir);
    var files = fs.readdirSync(filedir);
    var modules = [];
    for (var i in files) {
        var filename = files[i];
        var file = fs.statSync(filedir + '/' + filename);
        if(file.isDirectory()) {
            modules.push(filename);
        }
    }
    response.json(modules);
});

router.post('/module/save', function(request, response) {
    var filepath = path.join(__dirname, config.mockDir, request.body.module);
    console.log('make module directory: %s', filepath);
    if(!fs.existsSync(filepath)) {
        fs.mkdirSync(filepath);
    }
    response.json(true);
});

router.post('/module/rename', function(request, response) {
    var params = request.body;
    var oldPath = path.join(__dirname, config.mockDir, params.oldModule),
        newPath = path.join(__dirname, config.mockDir, params.newModule);
    console.log('rename module path: %s=>%s', oldPath, newPath);
    if(fs.existsSync(newPath)) {
        response.json(false);
    } else {
        fs.renameSync(oldPath, newPath);
        response.json(true);
    }
});

router.post('/module/delete', function(request, response) {
    var filepath = path.join(__dirname, config.mockDir, request.body.module);
    console.log('delete module: %s', filepath);
    deleteAllSync(filepath);
    response.json(true);
});

router.post('/data/tree', function(request, response) {
    var params = request.body;
    var nodes = {
        name: 'MOCK',
        open: true,
        root: true,
        leaf: false
    };
    readDirSync(path.join(__dirname, config.mockDir, params.module), nodes);
    response.json(nodes);
});

router.post('/data/save', function(request, response) {
    var params = request.body;
    if (params.type == 'folder') {
        var filepath = path.join(__dirname, config.mockDir, params.module, params.folder);
        console.log('make data directory: %s', filepath);
        if(fs.existsSync(filepath)) {
            response.json(false);
        } else {
            fs.mkdirSync(filepath);
            response.json(true);
        }
    } else if (params.type == 'file') {
        var filepath = path.join(__dirname, config.mockDir, params.module, params.folder + '/' + params.file);
        console.log('write data file: %s', filepath);
        if(params.created && fs.existsSync(filepath)) {
            response.json(false);
        } else {
            fs.writeFileSync(filepath, params.data, { flag: 'w', encoding: 'utf-8' });
            response.json(true);
        }
    }
});

router.post('/data/rename', function(request, response) {
    var params = request.body;
    var oldPath = path.join(__dirname, config.mockDir, params.module, params.oldPath),
        newPath = path.join(__dirname, config.mockDir, params.module, params.newPath);
    console.log('rename data path: %s=>%s', oldPath, newPath);
    if(fs.existsSync(newPath)) {
        response.json(false);
    } else {
        fs.renameSync(oldPath, newPath);
        response.json(true);
    }
});

router.post('/data/delete', function(request, response) {
    var params = request.body;
    var filepath = path.join(__dirname, config.mockDir, params.module, params.path);
    console.log('delete data: %s', filepath);
    deleteAllSync(filepath);
    response.json(true);
});

router.post('/data/copy', function(request, response) {
    var params = request.body;
    var source = path.join(__dirname, config.mockDir, params.module, params.source);
    var target = path.join(__dirname, config.mockDir, params.module, params.target);
    console.log('copy data: %s=>%s', source, target);
    if (params.type == 'folder') {
        params.root = true;
        copyFolder(source, target, params.ignore);
    } else if (params.type == 'file') {
        var filepath = path.dirname(target);
        if(!fs.existsSync(filepath)) {
            fs.mkdirSync(filepath);
        }
        copyFile(source, target, params.ignore);
    }
    response.json(true);
});

router.post('/data/test', function(request, response) {
    var params = request.body;
    var options = {
        url: params.url,
        method: params.method,
        json: true,
        headers: {
            'Content-Type': 'application/json;charset=UTF-8',
            'X-Requested-With': 'XMLHttpRequest'
        },
        timeout: 10000 // 10s
    };
    if (params.data != null) {
        options['body'] = params.data;
    }
    httpRequest(options).on('error', function(error) {
        console.log(error);
    }).pipe(response);
});

function copyFolder(source, target, ignore) {
    var copyable = ignore.root || ignore.folder;
    if (!fs.existsSync(target)) {
        copyable = true;
        fs.mkdirSync(target);
    }
    if (copyable) {
        ignore.root = false;
        var files = fs.readdirSync(source);
        for (var i in files) {
            var filename = files[i];
            var curpath = source + '/' + filename;
            var tgtpath = target + '/' + filename;
            if(fs.statSync(curpath).isDirectory()) {
                copyFolder(curpath, tgtpath, ignore);
            } else {
                copyFile(curpath, tgtpath, ignore);
            }
        }
    }
}

function copyFile(source, target, ignore) {
    if (!fs.existsSync(target) || ignore.file) {
        fs.createReadStream(source).pipe(fs.createWriteStream(target));
    }
}

function deleteAllSync(filepath) {
    if(fs.existsSync(filepath)) {
        if(fs.statSync(filepath).isDirectory()) {
            var files = fs.readdirSync(filepath);
            for (var i in files) {
                var filename = files[i];
                var curpath = filepath + '/' + filename;
                if(fs.statSync(curpath).isDirectory()) {
                    deleteAllSync(curpath);
                } else {
                    fs.unlinkSync(curpath);
                }
            }
            fs.rmdirSync(filepath);
        } else {
            fs.unlinkSync(filepath);
        }
    }
}

function readDirSync(filedir, srcnode) {
    var children = [];
    var files = fs.readdirSync(filedir);
    for (var i in files) {
        var filename = files[i];
        var subnode = {};
        subnode.name = filename;
        var file = fs.statSync(filedir + '/' + filename);
        if(file.isDirectory()) {
            subnode.leaf = false;
            readDirSync(filedir + '/' + filename, subnode);
        } else {
            subnode.leaf = true;
        }
        children.push(subnode);
    }
    srcnode.children = children;
}

module.exports = router;
